package cn.edu.bjtu.model.core;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import cn.edu.bjtu.api.NetworkModelService;
import cn.edu.bjtu.api.NeuronNetwork;
import cn.edu.bjtu.core.LoggerSupport;

abstract class Slave extends LoggerSupport implements NeuronNetwork,Serializable{
		private static final long serialVersionUID = 2731025633294068413L;
		protected final boolean detect;
		protected NetworkModelService nms;
		protected volatile long modelLastModifiedTime = -1L;
		//定时检测模型修改时间,每10S检测一下
		protected transient ScheduledExecutorService ses;
		private transient Thread modelLastModifiedTimePollingThread;
		
		protected Slave(NetworkModelService nms){
			this(nms,false);
		}
		
		public Slave(NetworkModelService nms,boolean detect){
			this.detect = detect;
			this.nms = nms;
			if(this.detect){
				startPolling();
			}
		}
		
		void startPolling(){
			ses = Executors.newScheduledThreadPool(1);
			modelLastModifiedTimePollingThread = new Thread(()->{
				long latestTime = -1;
				try{
					//防止发生异常导致的线程不正常结束.
					latestTime = nms.lastModifiedTime().getTime();
				}catch(Exception e){
					logException(e);
					return ;
				}
				if(modelLastModifiedTime != latestTime){
					logger.info(" Model modified time changed from {} to {} ",modelLastModifiedTime,latestTime);
					modelLastModifiedTime = latestTime;
				}
			});
			ses.scheduleWithFixedDelay(modelLastModifiedTimePollingThread, 1, 10, TimeUnit.SECONDS);
			logger.info(" Starting polling thread to detecting model modified time .... ");
		}
		/**
		 * 获取分类器实例
		 * @return
		 */
		abstract Object get();
		InputStream getStream(){
			byte [] res = nms.getModelFileStream();
			ByteArrayInputStream bais = new ByteArrayInputStream(res);
			return bais;
		}
	}